package com.swak;

import java.io.File;
import java.net.InetAddress;
import java.util.StringTokenizer;

import org.springframework.core.io.FileSystemResource;

import com.swak.codec.Digests;
import com.swak.codec.Encodes;
import com.swak.codec.ShortUrls;
import com.swak.utils.Ints;
import com.swak.utils.Nets;
import com.swak.utils.StringUtils;

/**
 * 操作系统
 *
 * @author: lifeng
 * @date: 2020/3/29 15:45
 */
public enum OS {

	/**
	 *
	 */
	linux,

	/**
	 *
	 */
	mac,

	/**
	 *
	 */
	windows,

	/**
	 *
	 */
	Others;

	/**
	 * 本机系统类型
	 *
	 * @return OS
	 */
	public static OS me() {
		String os = System.getProperty("os.name").toLowerCase();
		if (os.contains(OS.linux.name())) {
			return OS.linux;
		} else if (os.contains(OS.mac.name())) {
			return OS.mac;
		} else if (os.contains(OS.windows.name())) {
			return OS.windows;
		}
		return OS.Others;
	}

	/**
	 * 本机IP
	 *
	 * @return ip
	 */
	public static String ip() {
		try {
			return Nets.getLocalAddress().getHostAddress();
		} catch (Exception e) {
			return Constants.LOCALHOST;
		}
	}

	/**
	 * 本机 Mac
	 *
	 * @return mac
	 */
	public static String hardware() {
		try {
			return Nets.getHardwareAddress();
		} catch (Exception e) {
			return StringUtils.EMPTY;
		}
	}

	/**
	 * 对应机器的唯一编码；Jav_ + Mac + MD5(path)
	 * 
	 * @return
	 */
	public static String appID() {
		try {
			String mac = StringUtils.remove(OS.hardware(), "-");
			FileSystemResource resource = new FileSystemResource(StringUtils.EMPTY);
			File baseFile = resource.getFile().getAbsoluteFile();
			String file = baseFile.getAbsolutePath();
			String path = Encodes.encodeHex(Digests.md5(file.getBytes()));
			String path0 = ShortUrls.encode(path)[0];
			return "App_" + mac.toLowerCase() + path0;
		} catch (Exception e) {
			return "App_001";
		}
	}

	/**
	 * 本机主机名
	 *
	 * @return OS
	 */
	public static String hostName() {
		return Nets.getLocalAddress().getHostName();
	}

	/**
	 * 本机地址
	 *
	 * @return OS
	 */
	public static InetAddress localAddress() {
		return Nets.getLocalAddress();
	}

	/**
	 * 当前用户的home
	 *
	 * @return user.home
	 */
	public static String user() {
		return System.getProperty("user.name");
	}

	/**
	 * 当前用户的home
	 *
	 * @return user.home
	 */
	public static String home() {
		return System.getProperty("user.home");
	}

	/**
	 * 当前用户临时目录
	 *
	 * @return java.io.tmpdir
	 */
	public static String temp() {
		return System.getProperty("java.io.tmpdir");
	}

	/**
	 * 获取java 的版本
	 *
	 * @return user.home
	 */
	public static String java() {
		return System.getProperty("java.version");
	}

	/**
	 * 属性输出
	 *
	 * @return user.home
	 */
	public static String property(String name) {
		return System.getProperty(name);
	}

	/**
	 * 返回可用的线程用
	 * 
	 * @param max
	 * @return
	 */
	public static int eventLoops(int max) {
		return Ints.min(max, Constants.Available_Processors);
	}

	/**
	 * 随机可用端口： 10000 ~ 60000 之间
	 * 
	 * @return
	 */
	public static int randomAvailablePort() {
		int port = Ints.random(60000, 10000);
		boolean available = Nets.isAvailablePort(port);
		if (!available) {
			while (!available) {
				port = Ints.random(60000, 10000);
				available = Nets.isAvailablePort(port);
			}
		}
		return port;
	}

	/**
	 * 是否发布环境;
	 */
	public static boolean isProdEnv() {
		String env = System.getProperty("app.env", Env.dev.name());
		return Env.prod.name().equals(env);
	}

	/**
	 * 执行外部命令
	 * 
	 * @param strcmd
	 * @return
	 */
	public static boolean runCmd(String strcmd, String[] envp) {

		// split cmd
		StringTokenizer st = new StringTokenizer(strcmd);
		String[] cmdarray = new String[st.countTokens()];
		for (int i = 0; st.hasMoreTokens(); i++)
			cmdarray[i] = st.nextToken();

		// 执行命令
		Runtime rt = Runtime.getRuntime();
		Process ps = null;
		try {
			ps = rt.exec(cmdarray, envp, null);
			ps.waitFor();
		} catch (Exception e) {
			if (ps != null) {
				ps.destroy();
			}
			return false;
		}

		// 执行命令 -- 成功
		int i = ps.exitValue(); // 接收执行完毕的返回值
		ps.destroy(); // 销毁子进程
		ps = null;
		return i == 0;
	}

	/**
	 * 执行外部命令
	 * 
	 * @param strcmd
	 * @return
	 */
	public static boolean run(String strcmd) {
		return runCmd(strcmd, null);
	}

	/**
	 * 外部程序打开文件
	 * 
	 * @param file
	 */
	public static void open(String file) {
		String cmd = "";
		if (OS.me() == windows) {
			cmd = "cmd /c start " + file;
		} else {
			cmd = "/bin/sh -c " + file;
		}
		try {
			OS.runCmd(cmd, null);
		} catch (Exception e) {
		}
	}
}